package com.zqj.lambda;

import org.junit.Test;

import java.util.Comparator;
import java.util.function.Consumer;

/**
 * Lambda表达式的使用
 * 1.举例：(o1,o2) -> Integer.compare(o1,o2);
 * 2.格式：
 *     ——>: lambda操作符 或 箭头操作符
 *     ——>左边：lambda形参列表(其实就是接口中的抽象方法的形参列表)
 *     ——>右边：lambda体(其实就是重写的抽象方法的抽象体)
 * 3.Lambda表达式的使用：(分为6种情况介绍)
 *
 *     总结：
 *       ->左边：1。lambdb形参列表的参数类型可以省略(类型推断)；如果lambda形参列表只有一个参数时()也可以省略
 *       ->右边：lambda体应该使用一对{}包裹；如果lambda体只有一条执行语句(可能是return语句)，可以省略{}和retuen(省大括号必须省retuen)
 *
 * 4.lambda表达式的本质：作为函数式接口的实例
 * 5.如果一个接口中，只声明了一个抽象方法 那这个接口就是函数式接口。我们可以在接口上加@FunctionalInterface
 *  这样可以检查它是否是一个函数式接口
 *
 * 6.所以以前用匿名实现类表示的现在都可以用lambda表达式来写
 */
public class LambdaTest1 {
    //语法格式一：无参无返回值
    @Test
    public void test1(){
        //实现runnable接口的匿名实现类对象
        Runnable r1 = new Runnable(){
            @Override
            public void run() {
                System.out.println("小强牛逼呀！");
            }
        };
        r1.run();//就是简单的对象调方法
        System.out.println("*****************************");
        Runnable r2 = ()-> System.out.println("小强哥牛逼！");
        r2.run();

    }


    //语法格式二: Lambda需要一个参数，但是没有返回值
    @Test
    public void test2(){

        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("加油努力！");
        System.out.println("*************************");
        Consumer<String> con2 = (String s)-> {
            System.out.println(s);
        };
        con2.accept("我ijava！");

    }
    //语法格式三：数据类型可以省略，因为可以由编译器推断得出，称为类型推断
    public void test3(){
        Consumer<String> con2 = (String s)->{
            System.out.println(s);
        } ;
        con2.accept("我ijava！");
        System.out.println("********************");
        Consumer<String> consumer =(s)-> {
            System.out.println(s);
        };
        consumer.accept("强哥也爱Java！");

    }

    //语法格式四：lambda 若只需要一个参数时，参数的小括号可以省略
    @Test
    public void test4(){
        Consumer<String> consumer =(s)-> {
            System.out.println(s);
        };
        consumer.accept("强哥也爱Java！");
        System.out.println("*******************");
        Consumer<String> consumer2 = s->{
            System.out.println(s);
        };

        consumer2.accept("省略小括号！");
    }

    //语法格式五：Lambda需要两个以上的参数，多条执行语句，并且有返回值
    @Test
    public void test5(){
        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return o1.compareTo(o2);
            }
        };
        System.out.println(com1.compare(12, 21));
        System.out.println("*********************************");
        Comparator<Integer> com2 =(o1,o2)->{
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };

        System.out.println(com2.compare(2, 5));
    }

    //语法格式六：当lambda体只有一条语句时 return 与大括号若有，都可以省略
    @Test
    public void test7(){
        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(com1.compare(12, 21));
        System.out.println("*********************************");

        Comparator<Integer> com2 = (o1,o2)->o1.compareTo(o2);
        System.out.println(com2.compare(9,21));



        Consumer<String> con1 =s ->{
            System.out.println(s);
        };
        con1.accept("你好！");
        System.out.println("*********************");
        Consumer<String> con2 = s->System.out.println(s);
        con2.accept("我好");
    }


}
